package com.sf.osms.dep.quartz;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;

import com.sf.novatar.context.AppContext;
import com.sf.osms.dep.biz.ICommonServiceBiz;
import com.sf.osms.dep.domain.Agent;
import com.sf.osms.dep.processor.util.ExceptionUtils;
import com.sf.osms.dep.processor.util.ResourceUtils;

public class DynamicScheduleFactory{
	
	private static Logger logger = LoggerFactory.getLogger(DynamicScheduleFactory.class);
	public static void dynamicAddAgentEventJob(ApplicationContext context) {
		
		 			try {
					//schedulerFactoryBean 由spring创建注入
 					Scheduler scheduler = (Scheduler)context.getBean("schedulerFactoryBean");
					printScheduledJobs(scheduler);
					//这里获取任务信息数据
 					List<Agent> agentInfoes = context.getBean(ICommonServiceBiz.class).findAllAgentInfo();
					//进行代理到Job的组装
					 
					List<ScheduleJob> jobList = transferJobInfo(agentInfoes);
					for (ScheduleJob job : jobList) {
					 	TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
					 	//获取trigger，即在spring配置文件中定义的Trriger
					 	CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
				
					 	//不存在，创建一个
					 	if (null == trigger) {	
					 		if("1".equals(job.getJobStatus())){
					 			continue;
					 		}
					 		
					 		JobDetail jobDetail = JobBuilder.newJob(AgentJob.class)
					 			.withIdentity(job.getJobName(), job.getJobGroup()).build();
					 		jobDetail.getJobDataMap().put("agentInfo", job);
					 		//表达式调度构建器
					 		CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
					 		//按新的cronExpression表达式构建一个新的trigger
					 		trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup()).withSchedule(scheduleBuilder).build();
					 		scheduler.scheduleJob(jobDetail, trigger);
					 	}else{	
					 		
					 		if("1".equals(job.getJobStatus())){
					 			scheduler.deleteJob(JobKey.jobKey(job.getJobName(), job.getJobGroup()));
					 		}else{
					 			// Trigger已存在，那么更新相应的定时设置
								//表达式调度构建器
					 			String cronExpression = trigger.getCronExpression();
					 			if(!cronExpression.equalsIgnoreCase(job.getCronExpression())){
					 				CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
									//按新的cronExpression表达式重新构建trigger
									trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
										.withSchedule(scheduleBuilder).build();
									//按新的trigger重新设置job执行
									scheduler.rescheduleJob(triggerKey, trigger);
					 			}
								
					 		}
					 		
					 	}
					 }
		           
		      
			} catch (Exception e) {
				logger.error("动态添加代理JOB异常");
				logger.error(ExceptionUtils.getExceptionStackString(e));
			}
		
	}
	
	public static List<ScheduleJob> transferJobInfo(List<Agent> agentInfoes){
		List<ScheduleJob> jobs = new ArrayList<ScheduleJob>();
		for (Agent agent : agentInfoes) {
			ScheduleJob job = new ScheduleJob();
			job.setJobGroup("AGENT_ROUTER_FILE");
			job.setJobName(agent.getName());
			job.setJobStatus(agent.getIsDeleted()+""); //标识启动job 0标识没有删除，1标识代理删除
			String dep_scan_time = ResourceUtils.getApplicationConfig("dep_scan_time");
			if(StringUtils.isBlank(dep_scan_time)){
				dep_scan_time = "0 0/10 * * * * ?"; //默认10分钟
			}
			
			/**
			 * 代理的cron表达式有改变
			 */
			if(StringUtils.isNotBlank(agent.getCronExpression())){
				dep_scan_time = agent.getCronExpression();
			}
			
			job.setCronExpression(dep_scan_time.trim());
			job.setAgent(agent);
			jobs.add(job);
			
		}
		return jobs;
	}
	
	public static void printScheduledJobs(Scheduler scheduler) throws Exception{
		
		GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
		Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
		for (JobKey jobKey : jobKeys) {
		    List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
		    for (Trigger trigger : triggers) {
		        ScheduleJob job = new ScheduleJob();
		        job.setJobName(jobKey.getName());
		        job.setJobGroup(jobKey.getGroup());
		        job.setDesc("触发器:" + trigger.getKey());
		        Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
		        job.setJobStatus(triggerState.name());
		        if (trigger instanceof CronTrigger) {
		            CronTrigger cronTrigger = (CronTrigger) trigger;
		            String cronExpression = cronTrigger.getCronExpression();
		            job.setCronExpression(cronExpression);
		        }
		        logger.info("JobName:{},Job cronExpression:{},Job descrption:{}.",new String[]{job.getJobGroup()+job.getJobName(),job.getCronExpression(),job.getDesc()});
		    }
		}
	}

}
